using System;
using Synapse.Framework.Notifier;
using Synapse.Framework.Pipe.Operations;

namespace Synapse.Framework.Pipe.PipeLines
{
    public class PipeLineBuilder : IPipeLineBuilder
    {
        private readonly IPipeLine pipeLine;
        private readonly INotifier notifier;

        public PipeLineBuilder() : this(new PipeLine(),new TraceNotifier())
        {
        }

        public PipeLineBuilder(IPipeLine pipeLine,INotifier notifier)
        {
            this.pipeLine = pipeLine;
            this.notifier = notifier;
        }

        public IPipe<TInput, TOutput, TInput> Pin<TInput, TOutput>(IOperation<TInput, TOutput> operation)
        {
            return new Pipe<TInput, TInput, TOutput>(pipeLine, notifier).Pin(operation);
        }

        public IPipe<TInput, TOutput, TInput> Pin<TInput, TOutput>(Func<TInput,TOutput> operation)
        {
            return new Pipe<TInput, TInput, TOutput>(pipeLine, notifier).Pin(new OperationFuncAdapter<TInput, TOutput>(operation));
        }

        public IPipe<TInput, TOutput, TInput> Pin<TInput, TOutput>(Func<IPipe<TInput, TInput, TOutput>, IOperation<TInput, TOutput>> operation)
        {
            var pipe = new Pipe<TInput, TInput, TOutput>(pipeLine, notifier);
            return pipe.Pin(operation(pipe));
        }
    }
}